﻿package kliment.controls {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventPhase;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.clearInterval;
	import flash.utils.setInterval;
	
	/**
     * Dispatched when need show.
     */
    [Event(name = 'open', type = 'flash.events.Event')]
	/**
     * Dispatched when nedd hide.
     */
    [Event(name = 'close', type = 'flash.events.Event')]
	
	/**
	 * ...
	 * @author	Kliment
	 * @version	1.2.11
	 * 
	 * class name: kliment.controls.AutoHide
	 */
	public class AutoHide extends ControlsAbstract {
		private var _clocker:Sprite;
		private var _hitSpace_mc:Sprite;
		private var _delay:uint;
		private var _mouseOver:Boolean = true;
		private var _enableClick:Boolean = true;
		private var _intervalId:Number;
		
		public function AutoHide(hitSpace_mc:Sprite, delay:uint, enable:Boolean = true, enableClick:Boolean = true ) {
			_hitSpace_mc = hitSpace_mc;
			_delay = delay;
			_clocker = new Sprite();
			_enableClick = enableClick;
			this.enable = enable;
			
			_hitSpace_mc.addEventListener(Event.ADDED_TO_STAGE, _stageHandler);
			_hitSpace_mc.addEventListener(Event.REMOVED_FROM_STAGE, _stageHandler);
		}
		
		override public function set enable(value:Boolean):void {
			if (value) {
				_mouseOver = true;
				_clocker.addEventListener(Event.ENTER_FRAME, _hitHandler);
			} else {
				_clocker.removeEventListener(Event.ENTER_FRAME, _hitHandler);
				clearInterval(_intervalId);
			}
			enableClick = _enableClick;
			super.enable = value;
		}
		
		public function get enableClick():Boolean { return _enableClick; }
		public function set enableClick(value:Boolean):void {
			if (_hitSpace_mc.stage) {
				_hitSpace_mc.stage.removeEventListener(MouseEvent.MOUSE_UP, _clickHandler);
				if (value) {
					_hitSpace_mc.stage.addEventListener(MouseEvent.MOUSE_UP, _clickHandler);
				}
			}
			_enableClick = value;
		}
		
		private function _stageHandler(event:Event):void {
			switch(event.type) {
				case Event.ADDED_TO_STAGE:
					if (_enableClick)
						_hitSpace_mc.stage.addEventListener(MouseEvent.MOUSE_UP, _clickHandler);
				break;
				
				case Event.REMOVED_FROM_STAGE:
					_hitSpace_mc.stage.removeEventListener(MouseEvent.MOUSE_UP, _clickHandler);
				break;
			}
		}
		
		private function _hitHandler(event:Event):void {
			var hitTest:Boolean = _hitTest();
			if (hitTest && !_mouseOver) {
				show();
				_mouseOver = true;
			} else if (!hitTest && _mouseOver) {
				_hide();
				_mouseOver = false;
			}
		}
		
		private function _clickHandler(event:MouseEvent):void {
			if (!_enable) return;
			var hitTest:Boolean = _hitTest();
			if (!hitTest) {
				_mouseOver = false;
				hide();
			}
		}
		
		private function _hitTest():Boolean {
			var point:Point = _hitSpace_mc.localToGlobal(new Point(_hitSpace_mc.mouseX, _hitSpace_mc.mouseY));
			return _hitSpace_mc.hitTestPoint(point.x, point.y);
		}
		
		public function show():void {
			if (_enableClick && _hitSpace_mc.stage) {
				_hitSpace_mc.stage.addEventListener(MouseEvent.MOUSE_UP, _clickHandler);
			}
			_mouseOver = true;
			clearInterval(_intervalId);
			dispatchEvent(new Event(Event.OPEN));
		}
		
		private function _hide():void {
			clearInterval(_intervalId);
			_intervalId = setInterval(hide, _delay);
		}
		
		public function hide():void {
			if (_hitSpace_mc.stage && _hitSpace_mc.stage.hasEventListener(MouseEvent.MOUSE_UP)) 
				_hitSpace_mc.stage.removeEventListener(MouseEvent.MOUSE_UP, _clickHandler);
			clearInterval(_intervalId);
			dispatchEvent(new Event(Event.CLOSE));
		}
		
		public function remove():void {
			_hitSpace_mc.removeEventListener(Event.ADDED_TO_STAGE, _stageHandler);
			_hitSpace_mc.removeEventListener(Event.REMOVED_FROM_STAGE, _stageHandler);
			clearInterval(_intervalId);
			enable = false;
			enableClick = false;
		}
	}
	
}